package com.spark.tags;

import java.util.Iterator;
import java.util.List;

import com.spark.core.SparkBuilder;
import com.spark.core.SparkConfiguration;
import com.spark.core.SparkContext;
import com.spark.core.XMap;


/**
 * 
 * @version $Id: GridLayout.java v 1.0 2011-3-17 下午10:11:47 IBM Exp $
 * @author <a href="mailto:njq.niu@hand-china.com">vincent</a>
 */
public class GridLayout extends ViewComponent{
	
	public static final String ROWS = "row";
	public static final String COLUMNS = "column";
	
	protected static final int UNLIMITED = -1;
	protected static final String PROPERTITY_CELLPADDING = "cellPadding";
	protected static final String PROPERTITY_CELLSPACING = "cellSpacing";
	protected static final String PROPERTITY_VALIDALIGN = "validAlign";
	protected static final String PROPERTITY_PADDING = "padding";
	protected static final String PROPRRTITY_SHOW_BORDER = "showBorder";
	protected static final String PROPERTITY_PROMPT_STYLE ="promptStyle";
	
	protected static final String TITLE_CLASS = "layout-title";
	protected static final String DEFAULT_TABLE_CLASS = "layout-table";
	protected static final String DEFAULT_TD_CELL = "layout-td-cell";
	protected static final String DEFAULT_TD_CONTAINER = "layout-td-con";
	
	
	
	protected int getDefaultWidth(){
		return 0;
	}
	
	protected int getDefaultHeight(){
		return 0;
	}
		
	protected int getRows(XMap view){
		int rows = view.getInt(ROWS, UNLIMITED);
		return rows;
	}
	
	protected int getColumns(XMap view){
		int columns = view.getInt(COLUMNS, UNLIMITED);
		return columns;
	}
	
	private void buildCell(StringBuilder sb, SparkContext context, XMap view, XMap field) throws Exception{		
		int padding = view.getInt(PROPERTITY_PADDING, 3);
		String nameSpace = field.getNamespaceURI();
		String name = field.getName();
		SparkConfiguration configuratin = context.getSparkConfiguration();
		SparkTag tag = configuratin.getTag(nameSpace, name);
		if(tag instanceof GridLayout){
			beforeBuildCell(sb, context, view, field);
			sb.append("<td class='").append(DEFAULT_TD_CONTAINER).append("' style='padding:").append(padding).append("px'>");
		} else{
			beforeBuildCell(sb, context, view, field);
			sb.append("<td class='").append(DEFAULT_TD_CELL).append("' style='padding:").append(padding).append("px'>");
		}
		sb.append(SparkBuilder.build(field, context));
		sb.append("</td>");	
	}
		
	
	protected void beforeBuildCell(StringBuilder sb, SparkContext context, XMap view, XMap field) throws Exception{
	}
	
	protected void afterBuildCell(StringBuilder sb, SparkContext context, XMap field) throws Exception{
	}
	
	protected void buildHead(StringBuilder sb, SparkContext context,XMap view, int rows ,int columns) throws Exception{
	}
	
	protected void buildFoot(StringBuilder sb, SparkContext context,XMap view) throws Exception{
	}
	
	protected void afterBuildTop(StringBuilder sb, SparkContext context,XMap view) throws Exception{
	}
	
	@SuppressWarnings("unchecked")
	private void buildRows(StringBuilder sb, SparkContext context, XMap view, Iterator it) throws Exception{
		while(it.hasNext()){
			sb.append("<tr>");
			XMap field = (XMap)it.next();
			buildCell(sb,context,view,field);	
			sb.append("</tr>");
		}
	}
	
	
	@SuppressWarnings("unchecked")
	private void buildColumns(StringBuilder sb, SparkContext context, XMap view, Iterator it) throws Exception{
		sb.append("<tr>");
		while(it.hasNext()){
			XMap field = (XMap)it.next();
			buildCell(sb,context,view,field);		
		}
		sb.append("</tr>");
	}
	

	
	protected void buildTop(StringBuilder sb, SparkContext context, XMap view,int rows, int columns,String id) throws Exception{
		String cls = view.getString(PROPERTITY_CLASSNAME, "");
		String style = view.getString(PROPERTITY_STYLE, "");
		int cellspacing = view.getInt(PROPERTITY_CELLSPACING, 0);
		int cellpadding = view.getInt(PROPERTITY_CELLPADDING, 0);
		boolean showBorder = view.getBoolean(PROPRRTITY_SHOW_BORDER, false);

		
		int width = getComponentWidth(view, context);
		int height = getComponentHeight(view, context);
		
		String className = DEFAULT_TABLE_CLASS;
		className += " " + cls;
		
		if(showBorder) {
			cellspacing = 1;
			className += " layout-border";
		}
		
		sb.append("<table border=0 class='").append(className).append("' id='").append(id).append("'");
		if(width != 0) sb.append(" width=" + width);
		if(height != 0) sb.append(" height=" + height);
		if(!"".equals(style)) {
			sb.append(" style='").append(style).append("'");
		}
		
		sb.append(" cellpadding=").append(cellpadding).append(" cellspacing=").append(cellspacing+">");
		buildHead(sb,context,view, rows, columns);
		afterBuildTop(sb,context,view);
	}
	
	protected void buildBottom(StringBuilder sb, SparkContext context,XMap view) throws Exception{
		buildFoot(sb,context,view);
		sb.append("</tbody>");
		sb.append("</table>");	
	}
	
	public String execute(XMap view, SparkContext context) throws Exception{
		String id = (String)context.get(PROPERTITY_ID);
		
		StringBuilder sb = new StringBuilder();
		Iterator<XMap> it = view.getChildIterator();
		
		int rows = getRows(view);
		int columns = getColumns(view);
		if(rows == UNLIMITED && columns == UNLIMITED) {
			rows = UNLIMITED;
			columns = 1;
		}else if(rows == UNLIMITED && columns != UNLIMITED) {
			List<XMap> children = view.getChilds();
			if(children!=null){
				rows = (int)Math.ceil((double)view.getChilds().size()/columns);
			}else{
				rows = 1;				
			}
		} else if(rows != UNLIMITED && columns == UNLIMITED) {
			List<XMap> children = view.getChilds();
			if(children!=null){
				columns = (int)Math.ceil((double)view.getChilds().size()/rows);
			}else{
				columns = 1;				
			}
		}
		
		buildTop(sb, context, view, rows, columns, id);
		if (it != null) {
			if(rows == UNLIMITED){
				buildRows(sb,context, view, it);
			}else if(columns == UNLIMITED){
				buildColumns(sb, context, view, it);
			}else{
				for( int n=0; n<rows; n++){
					sb.append("<tr>");
					for( int k=0; k<columns; k++){
						if(it.hasNext()){
							XMap field = (XMap)it.next();
							buildCell(sb,context,view, field);	
						}else{
							sb.append("<th class='layout-th'></th><td class='layout-td-cell'></td>");
						}
					}
					sb.append("</tr>");
				}
			}
		}
		buildBottom(sb, context, view);
		return sb.toString();
	}	
}
